package com.yuzhi.common.util.redis;

import com.yuzhi.common.util.spring.SpringUtils;
import lombok.AccessLevel;
import lombok.NoArgsConstructor;
import org.redisson.api.RMap;
import org.redisson.api.RedissonClient;
import org.springframework.cache.Cache;
import org.springframework.cache.CacheManager;

import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.Set;
import java.util.concurrent.TimeUnit;

/**
 * @Description: 缓存操作工具类
 * @Author: sunshine
 * @Date: 2024-03-07
 */
@NoArgsConstructor(access = AccessLevel.PRIVATE)
@SuppressWarnings(value = {"unchecked"})
public class CacheUtils {

    private static final CacheManager CACHE_MANAGER = SpringUtils.getBean(CacheManager.class);

    private static final String SEQUENCE_CACHE_NAME = "dailySequence";
    private static final String DATE_KEY = "currentDate";

    /**
     * 获取缓存组内所有的KEY
     *
     * @param cacheNames 缓存组名称
     */
    public static Set<Object> keys(String cacheNames) {
        RMap<Object, Object> rmap = (RMap<Object, Object>) CACHE_MANAGER.getCache(cacheNames).getNativeCache();
        return rmap.keySet();
    }

    /**
     * 获取缓存值
     *
     * @param cacheNames 缓存组名称
     * @param key        缓存key
     */
    public static <T> T get(String cacheNames, Object key) {
        Cache.ValueWrapper wrapper = CACHE_MANAGER.getCache(cacheNames).get(key);
        return wrapper != null ? (T) wrapper.get() : null;
    }

    /**
     * 保存缓存值
     *
     * @param cacheNames 缓存组名称
     * @param key        缓存key
     * @param value      缓存值
     */
    public static void put(String cacheNames, Object key, Object value) {
        CACHE_MANAGER.getCache(cacheNames).put(key, value);
    }

    /**
     * 删除缓存值
     *
     * @param cacheNames 缓存组名称
     * @param key        缓存key
     */
    public static void evict(String cacheNames, Object key) {
        CACHE_MANAGER.getCache(cacheNames).evict(key);
    }

    /**
     * 清空缓存值
     *
     * @param cacheNames 缓存组名称
     */
    public static void clear(String cacheNames) {
        CACHE_MANAGER.getCache(cacheNames).clear();
    }


    /**
     * 获取缓存值
     *
     * @param cacheNames 缓存组名称K
     *                   缓存key活@param key
     *                   new
     **/
    public static Object get(String cacheNames) {
        Cache cache = CACHE_MANAGER.getCache(cacheNames);
        Object nativecache = cache.getNativeCache();
        return nativecache;
    }

    /**
     * 使用 Redis 的 AtomicLong 实现自增（设置过期时间）
     *
     * @param key Redis 全局唯一的 Key，例如 REPAIR_ORDER_NO:20250802
     *            建议使用业务前缀+日期/标识的命名方式，确保唯一性
     * @return 当前递增后的值（首次调用返回1，之后每次调用递增1）
     */
    public static Long incr(String key, long timeout, TimeUnit unit) {
        org.redisson.api.RedissonClient redissonClient = SpringUtils.getBean(org.redisson.api.RedissonClient.class);
        org.redisson.api.RAtomicLong atomicLong = redissonClient.getAtomicLong(key);
        if (!atomicLong.isExists()) {
            atomicLong.set(0);
            atomicLong.expire(timeout, unit); // 设置过期时间，确保每日清零
        }
        return atomicLong.incrementAndGet();
    }

    /**
     * 获取每日自增的四位序列号（格式：0001, 0002, ..., 9999）
     */
    public static String getDailyIncrementalSequence() {
        Cache cache = CACHE_MANAGER.getCache(SEQUENCE_CACHE_NAME);
        String today = LocalDate.now().format(DateTimeFormatter.ISO_DATE);

        // 检查日期是否变更（如果是新的一天，重置序列号）
        String lastDate = cache.get(DATE_KEY, String.class);
        if (!today.equals(lastDate)) {
            cache.put(DATE_KEY, today); // 更新日期
            cache.put("sequence", 0);   // 重置序列号
        }
        System.out.println(">>>>>>>>>>" + CACHE_MANAGER.getClass());
        // 自增序列号
        int sequence = cache.get("sequence", Integer.class) + 1;
        cache.put("sequence", sequence);

        // 格式化为4位数字（不足补零）
        return String.format("%04d", sequence);
    }

    /**
     * 保存缓存值并设置过期时间
     */
    public static void putWithExpiration(String cacheNames, Object key, Object value, long timeout, TimeUnit unit) {
        // 获取 RedissonClient 实例
        RedissonClient redissonClient = SpringUtils.getBean(RedissonClient.class);

        // 获取缓存的 Map 对象
        RMap<Object, Object> rMap = redissonClient.getMap(cacheNames);

        // 将数据存入缓存并设置过期时间
        rMap.put(key, value);  // 存储数据
        rMap.expire(timeout, unit);  // 设置缓存过期时间
    }


}
